#include <iostream>
#include <fstream>
#include <vector>
#include <list>
#include "project3.h"
using namespace std;

void Package::WriteToConsole()
{
    cout << PackageName << " ";
    cout << Value << " ";
    cout << Weight << " ";
    cout << endl;
}

Package * getPackages(char * name, int max)
{
	ifstream file;
	int fileNum;
	Package * packages;
	file.open(name);
	if(file.is_open()) 
	{
		//cout << "file open\n";
	} else {
		//cout << "file didn't open\n";
	}
	file >> fileNum;
	if (fileNum < max)
	{
		max = fileNum;
	}
	//cout << "Number of packages read: " << max << endl;
	packages = new Package[max];
    int temp;
	for (int i = 0; i < max; i++)
	{
		file >> packages[i].PackageName;
		file >> temp;
        packages[i].Value = static_cast<uint>(temp);
		file >> temp;
        packages[i].Weight = static_cast<uint>(temp);
	}
    file.close();
	return packages;
}

inline uint bit(uint i)
{
    return static_cast<uint>(1) << i;
}

SET ExhaustiveKnapsack(Package * packages, uint numOfPackages, uint maxPackageSize)
{
	SET best;
    SET subset;
    bool firstRun = true;
    uint lastBitMask = bit(numOfPackages) - 1;
	for (uint bit_mask = 0; bit_mask <= lastBitMask; ++bit_mask)
	{       
        subset.clear();
		for (uint i = 0; i < numOfPackages; ++i)
		{
			if (bit_mask & bit(i))
			{
				subset.push_back(&packages[i]);
			}
		}
		if (total_size(subset) > maxPackageSize)
		{
			continue;
		}
        if(firstRun)
        {
            best = subset;
            firstRun = false;
        }
        else if(total_votes(subset) > total_votes(best))
        {
            best = subset;
        }
	}
    return best;
}


uint total_votes(SET& set)
{
    uint votes = 0;
    for (SET::const_iterator it = set.begin(); it != set.end(); ++it)
    {
        votes += (*it)->Value;
    }
    return votes;
}

uint total_size(SET& set )
{
    uint size = 0;
    for (SET::const_iterator it = set.begin(); it != set.end(); ++it)
    {
        size += (*it)->Weight;
    }
    return size;
}

void PrintSet(SET& set)
{
    for (SET::iterator it = set.begin(); it!= set.end(); it++)
    {
        (*it)->WriteToConsole();
    }
    cout << "Total size = " << total_size(set) << " total votes = " << total_votes(set) << endl;
}